"""项目配置管理"""
import json
from pathlib import Path
from typing import Dict, Any
from src.base.registry import bera

class ProjectConfig:
    """项目配置管理类"""

    # 默认配置目录
    DEFAULT_PROJECT_DIR = "assets/projects/default"
    PROJECT_ROOT = "assets/projects"

    # 配置缓存
    _config: Dict[str, Any] = {}
    _project_dir: Path = None

    @classmethod
    def init(cls, project_dir: str = None) -> None:
        """初始化项目配置

        Args:
            project_dir: 项目根目录，如果不指定则使用默认目录

        Raises:
            ValueError: 当配置文件不存在或配置项缺失时
        """
        if project_dir is None:
            project_dir = cls.DEFAULT_PROJECT_DIR

        bera.logger.debug(f"初始化项目配置: project_dir={project_dir}")

        # 处理路径
        if not Path(project_dir).is_absolute():
            # 检查相对路径是否以assets/projects/开头
            if not project_dir.startswith('assets/projects/'):
                raise ValueError(f"项目目录必须在assets/projects/下,当前路径: {project_dir}")
            project_dir = Path(project_dir)
        else:
            # # 对于绝对路径,检查是否包含assets/projects
            # if 'assets/projects' not in str(project_dir):
            #     raise ValueError(f"项目目录必须在assets/projects/下,当前路径: {project_dir}")
            project_dir = Path(project_dir)

        # 保存项目目录
        cls._project_dir = project_dir
        bera.logger.debug(f"设置项目目录: _project_dir={cls._project_dir}")

        project_file = project_dir / "project.json"
        if not project_file.exists():
            raise ValueError(f"项目配置文件不存在: {project_file}")

        with open(project_file, 'r', encoding='utf-8') as f:
            cls._config = json.load(f)
            bera.logger.debug(f"加载配置文件: _config={cls._config}")

        # 验证必要的配置项
        required_configs = ['sql-dir', 'output-dir', 'config-dir', 'template-dir', 'workspace-dir']
        missing = [key for key in required_configs if key not in cls._config]
        if missing:
            raise ValueError(f"缺少必要的配置项: {', '.join(missing)}")

        # 设置可选配置项的默认值
        if 'autofilled' not in cls._config:
            cls._config['autofilled'] = []

    @classmethod
    def get_config(cls) -> Dict[str, Any]:
        """获取完整配置"""
        if not cls._config:
            cls.init()
        return cls._config

    @classmethod
    def get_project_dir(cls) -> Path:
        """获取项目根目录

        Returns:
            Path: 项目根目录的路径

        Raises:
            ValueError: 如果项目配置未初始化
        """
        bera.logger.debug(f"调用get_project_dir: _project_dir={cls._project_dir}")
        if cls._project_dir is None:
            cls.init()
        return cls._project_dir

    @classmethod
    def get_sql_dir(cls) -> Path:
        """获取SQL目录

        Returns:
            Path: SQL目录的完整路径(相对于项目根目录)
        """
        # 获取项目目录和sql-dir配置
        project_dir = cls.get_project_dir()
        sql_dir = Path(cls.get_config()['sql-dir'])
        bera.logger.debug(f"获取SQL目录: project_dir={project_dir}, sql_dir={sql_dir}")

        # 如果sql-dir是绝对路径，直接返回
        if sql_dir.is_absolute():
            return sql_dir

        # 否则，返回相对于项目目录的路径
        full_path = project_dir / sql_dir
        bera.logger.debug(f"返回完整SQL目录路径: {full_path}")
        return full_path

    @classmethod
    def get_output_dir(cls) -> Path:
        """获取输出根目录

        Returns:
            Path: 输出目录的完整路径(相对于项目根目录)
        """
        # 获取项目目录和output-dir配置
        project_dir = cls.get_project_dir()
        output_dir = Path(cls.get_config()['output-dir'])

        # 如果output-dir是绝对路径，直接返回
        if output_dir.is_absolute():
            return output_dir

        # 否则，返回相对于项目目录的路径
        return project_dir / output_dir

    @classmethod
    def get_config_dir(cls) -> Path:
        """获取配置目录

        Returns:
            Path: 配置目录的完整路径(相对于项目根目录)
        """
        # 获取项目目录和config-dir配置
        project_dir = cls.get_project_dir()
        config_dir = Path(cls.get_config()['config-dir'])

        # 如果config-dir是绝对路径，直接返回
        if config_dir.is_absolute():
            return config_dir

        # 否则，返回相对于项目目录的路径
        return project_dir / config_dir

    @classmethod
    def get_template_dir(cls) -> Path:
        """获取模板目录

        Returns:
            Path: 模板目录的完整路径(相对于项目根目录)
        """
        # 获取项目目录和template-dir配置
        project_dir = cls.get_project_dir()
        template_dir = Path(cls.get_config()['template-dir'])

        # 如果template-dir是绝对路径，直接返回
        if template_dir.is_absolute():
            return template_dir

        # 否则，返回相对于项目目录的路径
        return project_dir / template_dir

    @classmethod
    def get_table_output_path(cls, table_name: str) -> Path:
        """获取表输出路径"""
        return cls.get_output_dir() / 'tables' / table_name

    @classmethod
    def get_sql_file_path(cls, table_name: str) -> Path:
        """获取SQL文件路径"""
        return cls.get_sql_dir() / f"{table_name}.sql"

    @classmethod
    def get_workspace_dir(cls) -> Path:
        """获取工作空间目录

        Returns:
            Path: 工作空间目录的完整路径
        """
        # 获取项目目录和workspace-dir配置
        project_dir = cls.get_project_dir()
        workspace_dir = Path(cls.get_config()['workspace-dir'])
        bera.logger.debug(f"获取工作空间目录: project_dir={project_dir}, workspace_dir={workspace_dir}")

        # 如果workspace-dir是绝对路径，直接返回
        if workspace_dir.is_absolute():
            return workspace_dir

        # 否则，返回相对于项目目录的路径
        full_path = project_dir / workspace_dir
        bera.logger.debug(f"返回完整工作空间目录路径: {full_path}")
        return full_path

    @classmethod
    def get_project_info(cls) -> Dict[str, str]:
        """获取项目信息,包括版本号、公司名称等

        Returns:
            Dict[str, str]: 项目信息字典
        """
        # 默认值
        defaults = {
            "version": "1.0.1",
            "company": "上海火金网络科技有限公司",
            "author": "MiaoMa",
            "website": "https://www.miaoma.com",
            "copyright": "Copyright © 2025 上海火金网络科技有限公司. All rights reserved."
        }

        # 从配置中获取
        config = cls.get_config()

        # 直接使用根级别的配置，配置文件中的值优先
        return {**defaults, **config}

    @classmethod
    def get_autofilled_fields(cls) -> list:
        """获取自动填充字段集合

        Returns:
            list: 自动填充字段名列表，如 ['create_time', 'update_time', 'create_by', 'update_by']
        """
        config = cls.get_config()
        return config.get('autofilled', [])

    @classmethod
    def is_autofilled_field(cls, field_name: str) -> bool:
        """判断字段是否为自动填充字段

        Args:
            field_name: 字段名

        Returns:
            bool: 如果是自动填充字段返回True，否则返回False
        """
        autofilled_fields = cls.get_autofilled_fields()
        return field_name in autofilled_fields

    @classmethod
    def ensure_dirs(cls) -> None:
        """确保所有必要的目录存在"""
        cls.get_sql_dir().mkdir(parents=True, exist_ok=True)
        cls.get_output_dir().mkdir(parents=True, exist_ok=True)
        cls.get_config_dir().mkdir(parents=True, exist_ok=True)
        cls.get_template_dir().mkdir(parents=True, exist_ok=True)